package com.rocksea.app.http;

import android.content.Context;
import android.util.Log;

import com.mor.dataacquisition.net.BaseParser;
import com.mor.dataacquisition.net.RequestValue;
import com.mor.dataacquisition.vo.sonicWave.SonicWave;
import com.mor.dataacquisition.vo.sonicWave.SonicWaveData;
import com.mor.dataacquisition.vo.sonicWave.SonicWaveFace;
import com.rocksea.app.Account;
import com.rocksea.app.db.DbCenter;
import com.rocksea.app.db.UpLoadingTable;
import com.rocksea.app.db.UploadingDbHelper;
import com.rocksea.app.db.history.HistoryTable;
import com.rocksea.app.db.image.ImageTable;
import com.rocksea.app.entry.PileInfo;
import com.rocksea.app.utils.HttpMessage;
import com.rocksea.app.utils.PerUtils;
import com.rocksea.app.weight.SonicWaveImage;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import org.restlet.data.Form;

import java.io.File;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;

/**
 * @author by Mrw_v @date on 2018/8/21
 */

public class UpLoadSonicWaveThread extends Thread
{
    private static final int UPLOAD_THREAD_COUNT = 20;
    private Context context;
    private com.rocksea.app.db.SonicWave.SonicWave sonicWave;
    private long planId;
    private PileInfo pileInfo;
    private UploadWaveListenerImpl uploadWaveListener;
    private static boolean working = true;

    private static int currentProcess = 0;
    private static int maxProcess = 100;
    private static int completeCount = 0;

    private UpLoadSonicWaveThread()
    {
        super("UpLoadSonicWaveThread");
    }

    public UpLoadSonicWaveThread(com.rocksea.app.db.SonicWave.SonicWave sonicWave,Context context)
    {
        this();
        this.sonicWave = sonicWave;
        this.context = context;
        this.planId = sonicWave.inspectionFormId;
        this.pileInfo = new PileInfo();
        this.pileInfo.setBasicInfoId(sonicWave.uuid);
        this.pileInfo.setPileId(String.valueOf(sonicWave.pileId));
        this.pileInfo.setPlanId(this.planId);
        this.pileInfo.setSerilNo(sonicWave.inspectionFormNum);

        uploadWaveListener = new UploadWaveListenerImpl();
        working = true;
        currentProcess = 0;
        maxProcess = sonicWave.SonicWaveDatas.size();
        completeCount = 0;
    }

    public static void exitUploadThread()
    {
        working = false;
        try
        {
            UploadImageThread.exitUploadImageThread();
            interrupted();
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }
    }

    @Override
    public void run()
    {
        super.run();
        //上传基本信息
        if (pileInfo.getPileId().equals(""))
        {
            Log.e("UpLoadSonicWaveThread", "pileInfo异常");

            return;
        }
        long serviceId = DbCenter.mScDbHelper.queryServiceId(sonicWave.uuid);
        if (serviceId > 0)
        {
            HttpUtil.postEvent(HttpUtil.UploadEvent.NORMAL,"正在上传剖面");
            int waveFaceCode = uploadSonicWaveFace(serviceId,sonicWave);
            if (waveFaceCode == 0)
            {
                final HashMap<String,Integer> tude = new HashMap<>();
                for (int i = 0; i < sonicWave.SonicWaveFaces.size(); i++)
                {
                    tude.put(sonicWave.SonicWaveFaces.get(i).sectionId,sonicWave.SonicWaveFaces.get(i).tubeDistance);
                }

                int perSize = sonicWave.SonicWaveDatas.size() / UPLOAD_THREAD_COUNT;
                for (int i = 0; i < UPLOAD_THREAD_COUNT; i++)
                {
                    List<com.rocksea.app.db.SonicWave.SonicWave.SonicWaveData> datas = new ArrayList<>();
                    if (i == UPLOAD_THREAD_COUNT -1)
                    {
                        for (int m = (UPLOAD_THREAD_COUNT -1)*perSize; m < sonicWave.SonicWaveDatas.size() ; m++)
                        {
                            datas.add(sonicWave.SonicWaveDatas.get(m));
                        }
                        UpLoadWaveDataThread upLoadWaveDataThread = new UpLoadWaveDataThread(datas,serviceId,tude,context);
                        upLoadWaveDataThread.setOnUploadListener(uploadWaveListener);
                        upLoadWaveDataThread.start();
                        Log.i("run: ","start >"+i);
                        continue;
                    }
                    for (int n = 0; n < perSize; n++)
                    {
                        datas.add(sonicWave.SonicWaveDatas.get(perSize*i+n));
                    }
                    UpLoadWaveDataThread upLoadWaveDataThread = new UpLoadWaveDataThread(datas,serviceId,tude,context);
                    upLoadWaveDataThread.setOnUploadListener(uploadWaveListener);
                    upLoadWaveDataThread.start();
                    Log.i("run: ","start >"+i);
                }
            }
            else
            {
                HttpUtil.postEvent(HttpUtil.UploadEvent.WARM,"上传已取消");
            }
        }
        else
        {
            int pileId = Integer.valueOf(pileInfo.getPileId());
            HttpUtil.postEvent(HttpUtil.UploadEvent.NORMAL,String.format("正在上传%s桩基本信息",sonicWave.pileNo));
            int rerunCode = upLoadWaveBase(sonicWave, (int) planId, pileInfo.getSerilNo(), pileId);
            if (rerunCode > 0)
            {
                HttpUtil.postEvent(HttpUtil.UploadEvent.NORMAL,"正在上传剖面");
                DbCenter.insertSonicWaveServiceId(pileInfo.getBasicInfoId(),rerunCode); //更新数据库
                int faceCode = uploadSonicWaveFace(rerunCode,sonicWave);
                if (faceCode == 0)
                {
                    HttpUtil.postEvent(HttpUtil.UploadEvent.NORMAL,"剖面上传成功");
                    DbCenter.makeAsSonicWaveFaceUpLoad(sonicWave.uuid);
                    final HashMap<String,Integer> tude = new HashMap<>();
                    for (int i = 0; i < sonicWave.SonicWaveFaces.size(); i++)
                    {
                        tude.put(sonicWave.SonicWaveFaces.get(i).sectionId,sonicWave.SonicWaveFaces.get(i).tubeDistance);
                    }
                    int perSize = sonicWave.SonicWaveDatas.size() / UPLOAD_THREAD_COUNT;
                    for (int i = 0; i < UPLOAD_THREAD_COUNT; i++)
                    {
                        List<com.rocksea.app.db.SonicWave.SonicWave.SonicWaveData> datas = new ArrayList<>();
                        if (i == UPLOAD_THREAD_COUNT -1)
                        {
                            for (int m = (UPLOAD_THREAD_COUNT -1)*perSize; m < sonicWave.SonicWaveDatas.size() ; m++)
                            {
                                datas.add(sonicWave.SonicWaveDatas.get(m));
                            }
                            UpLoadWaveDataThread upLoadWaveDataThread = new UpLoadWaveDataThread(datas,(long) rerunCode,tude,context);
                            upLoadWaveDataThread.setOnUploadListener(uploadWaveListener);
                            upLoadWaveDataThread.start();
                            continue;
                        }
                        for (int n = 0; n < perSize; n++)
                        {
                            datas.add(sonicWave.SonicWaveDatas.get(perSize*i+n));
                        }
                        UpLoadWaveDataThread upLoadWaveDataThread = new UpLoadWaveDataThread(datas,(long) rerunCode,tude,context);
                        upLoadWaveDataThread.setOnUploadListener(uploadWaveListener);
                        upLoadWaveDataThread.start();
                    }
                }
                else
                {
                    HttpUtil.postEvent(HttpUtil.UploadEvent.WARM,"上传已取消");
                }
            }
            else if (rerunCode == -91)
            {
                HttpUtil.postEvent(HttpUtil.UploadEvent.WARM,"上传已取消");
            }
        }
    }

    private int upLoadWaveBase(com.rocksea.app.db.SonicWave.SonicWave sonicWave,int planId,String planNum,int pileId)
    {
        SonicWave checkSonicWave = sonicWave.getBJTKSonicWave(planId,planNum,pileId);
        int checkCode = Integer.valueOf(checkSonicWave.validate()).intValue();
        if (checkCode != 0)
        {
            return checkCode;
        }
        else
        {
            RequestValue rValue = new RequestValue();
            rValue.context = context;
            rValue.url = Config.BASE_URL+Config.uploadSonicWave;
            rValue.parser = new BaseParser();

            while (working && isAlive())
            {
                Form form = new Form();
                JSONObject json = new JSONObject();
                try
                {
                    json = checkSonicWave.toJSONObject();
                }
                catch (JSONException e)
                {
                    e.printStackTrace();
                }
                form.add("sw", json.toString());
                int returnCode = HttpUtil.doNetRest(rValue,form);
                if (returnCode > 0)
                {
                    return returnCode;
                }
                else if (returnCode == -1)
                {
                    Account.setRandomCode(HttpUtil.upDateRandomCode());
                    checkSonicWave.randomCode = Account.getRandomCode();
                }
                else
                {
                    try
                    {
                        sleep(1000);
                    } catch (InterruptedException e)
                    {
                        e.printStackTrace();
                    }
                    HttpUtil.postEvent(HttpUtil.UploadEvent.ERROR,String.format("%s桩信息上传失败(%s),正在重试",
                            sonicWave.pileNo,HttpMessage.getErrorInfo(HttpMessage.uploadSonicWave,returnCode)));
                }
            }
            return -91;
        }
    }

    private int uploadSonicWaveFace(long serviceId, com.rocksea.app.db.SonicWave.SonicWave sonicWave)
    {
        ArrayList<SonicWaveFace> sonicWaveFaces = new ArrayList<>();
        for (int i = 0; i < sonicWave.SonicWaveFaces.size(); i++)
        {
            if (sonicWave.SonicWaveFaces.get(i).upLoadTime == 0)
            {
                sonicWaveFaces.add(sonicWave.getBJTKWaveFace(sonicWave.SonicWaveFaces.get(i)));
            }
        }

        //剖面都已经上传成功了
        if (sonicWaveFaces.size() == 0)
        {
            return 0;
        }
        int i = 0;
        for (SonicWaveFace sonicWaveFace : sonicWaveFaces)
        {
            ++i;
            String checkCode = sonicWaveFace.validate();
            if (!"0".equals(checkCode))
            {
                return Integer.valueOf(i + checkCode).intValue() * -1;
            }
        }
        RequestValue rValue = new RequestValue();
        rValue.context = context;
        rValue.url = Config.BASE_URL+Config.uploadSonicWaveFace;
        rValue.parser = new BaseParser();
        while (working && isAlive())
        {
            Form form = new Form();
            JSONArray jsonList = new JSONArray();
            try
            {
                for (SonicWaveFace sonicWaveFace : sonicWaveFaces)
                {
                    JSONObject json = sonicWaveFace.toJSONObject();
                    jsonList.put(json);
                }
            } catch (JSONException var12) {
                var12.printStackTrace();
            }
            form.add("randomCode", Account.getRandomCode());
            form.add("account", Account.getAccount());
            form.add("sonicWaveId", "" + serviceId);
            form.add("swfList", jsonList.toString());
            int returnCode = HttpUtil.doNetRest(rValue,form);
            if (returnCode == 0 || returnCode == -98 || returnCode == -101 || returnCode == -201|| returnCode == -301 || returnCode == -401 || returnCode == -501 || returnCode == -601)
            {
                DbCenter.makeAsSonicWaveFaceUpLoad(sonicWave.uuid);
                return 0;
            }
            else if (returnCode == -1)
            {
                Account.setRandomCode(HttpUtil.upDateRandomCode());
            }
            else
            {
                Log.d("uploadSonicWaveFace: ","剖面上传失败，1s后重试");
                HttpUtil.postEvent(HttpUtil.UploadEvent.ERROR,"剖面上传失败，正在重试...");
                try {
                    sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
        return -91;
    }



    private class UpLoadWaveDataThread extends Thread
    {
        private List<com.rocksea.app.db.SonicWave.SonicWave.SonicWaveData> sonicWaveData;
        private com.rocksea.app.db.SonicWave.SonicWave sonicWave;
        private long serviceId;
        private HashMap<String,Integer> tude;
        private Context context;
        private UpLoadWaveDataThread()
        {
            super("UpLoadWaveDataThread");
        }
        private UpLoadWaveDataThread(List<com.rocksea.app.db.SonicWave.SonicWave.SonicWaveData> sonicWaveData,
                                    long serviceId,HashMap<String,Integer> tude,Context context)
        {
            this();
            sonicWave = new com.rocksea.app.db.SonicWave.SonicWave();
            this.sonicWaveData = sonicWaveData;
            this.serviceId = serviceId;
            this.tude = tude;
            this.context = context;
        }
        
        private OnUploadListener onUploadListener;
        private void setOnUploadListener(OnUploadListener onUploadListener)
        {
            this.onUploadListener = onUploadListener;
        }
        
        
        @Override
        public void run()
        {
            super.run();
            String sectionId = null;
            for (com.rocksea.app.db.SonicWave.SonicWave.SonicWaveData sonicWaveDatum : sonicWaveData)
            {
                if (!working)
                {
                    HttpUtil.postEvent(HttpUtil.UploadEvent.WARM,"上传已取消");
                    break;
                }
                synchronized (UpLoadSonicWaveThread.class)
                {
                    currentProcess++;
                }
                if (DbCenter.mUploadFlagDbHelper.isUpLoad(sonicWaveDatum.uuid))
                    continue;
                HttpUtil.postEvent(HttpUtil.UploadEvent.NORMAL,String.format("正在上传测点数据(%.1f%%)...",((float)currentProcess)/maxProcess*100));
                sectionId = sonicWaveDatum.sectionId;
                SonicWaveData sonicWaveData = sonicWave.getBJTKWaveData(sonicWaveDatum,serviceId,tude);
                int checkCode = Integer.valueOf(sonicWaveData.validate()).intValue();
                if(checkCode != 0)
                {
                    Log.e("checkCode" ,checkCode+"");
                    if (onUploadListener != null)
                        onUploadListener.onUploadFail(HttpMessage.uploadSonicWaveData,checkCode);
                    break;
                }
                else
                {
                    RequestValue rValue = new RequestValue();
                    rValue.context = context;
                    rValue.url = Config.BASE_URL+Config.uploadSonicWaveData;
                    rValue.parser = new BaseParser();
                    while (working && isAlive())
                    {
                        Form form = new Form();
                        JSONObject json = new JSONObject();
                        try
                        {
                            json = sonicWaveData.toJSONObject();
                        }
                        catch (JSONException var7)
                        {
                            var7.printStackTrace();
                        }
                        form.add("swd", json.toString());
                        int returnCode = HttpUtil.doNetRest(rValue,form);
                        Log.d("UpLoadWaveDataThread", "code: "+returnCode);
                        if (returnCode == 0 || returnCode == -98)
                        {
                            DbCenter.makeFlagTableUploaded(sonicWaveDatum.uuid);
                            break;
                        }
                        else if (returnCode == -1)
                        {
                            try
                            {
                                sleep(500);
                            } catch (InterruptedException e)
                            {
                                e.printStackTrace();
                            }
                            Account.setRandomCode(updateRandomCode());
                            sonicWaveData.randomCode = Account.getRandomCode();
                        }
                        else
                        {
                            try
                            {
                                sleep(1000);
                            } catch (InterruptedException e)
                            {
                                e.printStackTrace();
                            }
                        }
                    }
                }
            }
            //如果某个剖面的数据在以前全部上传 也会标记一次该剖面数据上传成功
            if (onUploadListener != null && working)
                onUploadListener.onUploadComplete(sectionId);
        }
    }
    
    private interface OnUploadListener
    {
        void onUploadFail(int uploadInterface,int returnCode);
        void onUploadComplete(String sectionId);
    }

    private class UploadWaveListenerImpl implements OnUploadListener
    {

        private UploadWaveListenerImpl() {}

        @Override
        public void onUploadFail(int uploadInterface,int returnCode)
        {
            Log.d("onUploadComplete: ","失败");
            HttpUtil.postEvent(HttpUtil.UploadEvent.ERROR,String.format("测点上传异常(%s)",HttpMessage.getErrorInfo(uploadInterface,returnCode)));
            working = false;
            currentProcess = 0;
            maxProcess = 100;
            completeCount = 0;
        }

        @Override
        public void onUploadComplete(String sectionId)
        {
            synchronized (this)
            {
                completeCount++;
            }
            Log.i( "onUploadComplete",": ------>"+ completeCount);
            if (completeCount == UPLOAD_THREAD_COUNT) // complete == sectionCount
            {
                Log.d("onUploadComplete: ","成功");
                DbCenter.makeAsUpLoaded(sonicWave.uuid,2);
                HttpUtil.postEvent(HttpUtil.UploadEvent.NORMAL,"数据上传完成");
                UploadingDbHelper.makeUnloading(sonicWave.uuid, HistoryTable.TEST_SC,UpLoadingTable.DEFAULT_UUID);
                currentProcess = 0;
                maxProcess = 100;
                completeCount = 0;
                DrawSonicWaveBitmapThread.drawSonicWaveBitmap(sonicWave);
            }
        }
    }

    public static class DrawSonicWaveBitmapThread extends Thread
    {
        private Runnable mRunnable;

        private DrawSonicWaveBitmapThread()
        {
            super("DrawSonicWaveBitmapThread");
        }

        private DrawSonicWaveBitmapThread(Runnable runnable)
        {
            this();
            this.mRunnable = runnable;
        }

        @Override
        public void run()
        {
            super.run();
            if (mRunnable != null)
                mRunnable.run();
        }

        public static void drawSonicWaveBitmap(final com.rocksea.app.db.SonicWave.SonicWave sonicWave)
        {
            Runnable drawBitmapTask = new Runnable()
            {
                @Override
                public void run()
                {
                    ArrayList<String> sectionIds = new ArrayList<>();
                    for (int i = 0; i < sonicWave.SonicWaveFaces.size(); i++)
                    {
                        HttpUtil.postEvent(HttpUtil.UploadEvent.NORMAL,String.format("正在绘制波列图(%s/%s)",i+1,sonicWave.SonicWaveFaces.size()));
                        sectionIds.add(sonicWave.SonicWaveFaces.get(i).sectionId);
                        ArrayList<com.rocksea.app.db.SonicWave.SonicWave.SonicWaveData> sonicWaveData = new ArrayList<>();
                        for (com.rocksea.app.db.SonicWave.SonicWave.SonicWaveData waveData : sonicWave.SonicWaveDatas)
                        {
                            if (waveData.sectionId.equals(sectionIds.get(i)))
                            {
                                sonicWaveData.add(waveData);
                            }
                        }
                        File file = SonicWaveImage.drawSonicWaveBitmap(sonicWaveData,sectionIds.get(i));
                        if (file == null)
                        {
                            HttpUtil.postEvent(HttpUtil.UploadEvent.ERROR,"绘制波列异常");
                            continue;
                        }
                        ImageTable imageTable = new ImageTable();
                        imageTable.setCreatTime(PerUtils.dateToStr(new Date()));
                        imageTable.setFileName(file.getName());
                        imageTable.setRemake("RS波列图");
                        imageTable.setIsSonicWave(1);
                        imageTable.setFilePath(file.getPath());
                        imageTable.setPlanNum(sonicWave.inspectionFormNum);
                        imageTable.setPileNo(sonicWave.pileNo);
                        imageTable.setType(3);
                        imageTable.setSectionId(sectionIds.get(i));
                        imageTable.setPileId(sonicWave.inspectionFormId);
                        DbCenter.mImageDbHelper.insert(imageTable);
                    }

                    HttpUtil.postEvent(HttpUtil.UploadEvent.NORMAL,"开始上传现场照片");
                    UploadImageThread uploadImageThread = new UploadImageThread(sonicWave.inspectionFormNum,sonicWave.pileNo);
                    uploadImageThread.start();
                }
            };
            new DrawSonicWaveBitmapThread(drawBitmapTask).start();
        }
    }

    private synchronized String updateRandomCode()
    {
        return HttpUtil.upDateRandomCode();
    }


}